import java.io.*;


public class CodeGenerator
{
	public CodeGenerator(){
	
	}
	
	/*	
	Generator function generates the cpp object code of the source program.
	*/
	public static void generator(data dat,Lexer lex)
	{
			
		//First it opens a new file for writing the cpp object code.

			try{
				dat.outFile = new FileWriter(dat.filename+".cpp");
				dat.out = new PrintWriter(dat.outFile);
			    }catch(Exception e){}
			    
		//It writes the standard header files to be included in the cpp code.
			    
			dat.token= new StringBuffer("0");
			StringBuffer temp= new StringBuffer("#");
			dat.out.println("#include<iostream>");
			dat.out.println("using namespace std"+";");
			dat.out.println("int main()");
			dat.out.println("{");
				
		//Initialising the variables used in th program.	
				
			for(int x=0;x<dat.var_count;x++)
			dat.out.println("float "+dat.variables[x]+"=0;");
			
		//Generating the equivalent cpp code of the program
			
			while(!dat.token.toString().equalsIgnoreCase(temp.toString()))
			{
				dat.token = lex.lexer(dat);
				
				if((dat.code == 2)&&(dat.token.toString().equalsIgnoreCase("INPUT")))
				{
					dat.out.print("cin>>");
					
					dat.token = lex.lexer(dat);
					
					{
						if(dat.code ==3)
						{
							dat.out.print(dat.token);
							
							dat.token = lex.lexer(dat);
							
							
							if((dat.code ==6 )&&(dat.token.toString().equalsIgnoreCase(";")))
							{
								dat.out.println(dat.token);
								
							}
							
						}
					
					}
				}
				else
				{
					if((dat.code == 2)&&(dat.token.toString().equalsIgnoreCase("OUTPUT")))
					{
						dat.out.print("cout<<");
						dat.token = lex.lexer(dat);
						{
							if((dat.code==6)&&(dat.token.toString().equalsIgnoreCase("\"")))
							{
								dat.out.print(dat.token);
								do
								{
									dat.token = lex.lexer(dat);
									if(!dat.token.toString().equalsIgnoreCase("\\"))
									dat.out.print(dat.token+" ");
									else
									dat.out.print(dat.token);
								}while(!dat.token.toString().equalsIgnoreCase("\""));
								dat.token = lex.lexer(dat);
							
							}
							else
							{	
								expression_generator(dat,lex);
							}
							if((dat.code == 6)&&(dat.token.toString().equalsIgnoreCase(";")))
							{
								dat.out.println(dat.token);
								
							}
						}
					}
					else							
					{
						if((dat.code == 2)&&(dat.token.toString().equalsIgnoreCase("GOTO")))
						{
							dat.out.print("goto ");
							dat.token = lex.lexer(dat);
							{
								if(dat.code ==3)
								{
									dat.out.print(dat.token);
									dat.token = lex.lexer(dat);
									if((dat.code ==6)&&(dat.token.toString().equalsIgnoreCase(";")))
									{
										dat.out.println(dat.token);
										
									}
									
								}
							
							}	
						}
						else
						{
							if((dat.code ==2)&&(dat.token.toString().equalsIgnoreCase("IF")))
							{	
								dat.out.print("if");
								dat.token = lex.lexer(dat);
								condition_generator(dat,lex);
								if((dat.code ==2)&&(dat.token.toString().equalsIgnoreCase("GOTO")))
								{
									dat.out.print("\n");
									dat.out.print("goto ");
									dat.token = lex.lexer(dat);
									{
										
										if(dat.code ==3)
										{
											dat.out.print(dat.token);
											dat.token = lex.lexer(dat);
											
											if((dat.code ==6)&&(dat.token.toString().equalsIgnoreCase(";")))
											{
												dat.out.println(dat.token);
										
											}
											
										}
										
									}	
								}
							}
							else
							{
								if(dat.code == 3)
								{
								
									/* write here for assignment statement*/
									dat.out.print(dat.token);
									dat.token = lex.lexer(dat);
									if((dat.code == 5)&&(dat.token.toString().equalsIgnoreCase("=")))
									{
										dat.out.print(dat.token);
										dat.token = lex.lexer(dat);
										expression_generator(dat,lex);
										
										if((dat.code == 6)&&(dat.token.toString().equalsIgnoreCase(";")))
										{
											dat.out.println(dat.token);
										
										}
										
									}
									
									else
									{
										if((dat.code ==6)&&(dat.token.toString().equalsIgnoreCase(":")))
										{
											dat.out.println(dat.token);
										
										}
									
									
										
									}
								}
								else
									{
										if(dat.token.toString().equalsIgnoreCase("/"))
										{
											dat.out.print(dat.token);
											dat.token = lex.lexer(dat);
											if((dat.code==4)&&(dat.token.toString().equalsIgnoreCase("*")))
											{
												
												do
												{
													if(dat.code!=4)
													dat.out.print(" "+dat.token);
													else
													dat.out.print(dat.token);
													dat.token = lex.lexer(dat);
													
												}while(!dat.token.toString().equalsIgnoreCase("*"));
												dat.out.print(dat.token);
												dat.token = lex.lexer(dat);
												dat.out.print(dat.token+"\n");
												
											}							
										}							
										else
										{
											if(dat.token.toString().equalsIgnoreCase("#"))
											{
											}
											else
												{
																
												}
										}
									}				
							}
					}
				}
			}
		}
		dat.out.println("}");
		dat.out.close();
	}
	
	
	/*
	
	Generating the object code of the expression statement
	
	*/
	public static void expression_generator(data dat,Lexer lex)
	{
		if((dat.code ==6)&&(dat.token.toString().equalsIgnoreCase("(")))
		{
			dat.out.print(dat.token);
			dat.token = lex.lexer(dat);
			expression_generator(dat,lex);
			if((dat.code == 6)&&(dat.token.toString().equalsIgnoreCase(")")))
			{
				dat.out.print(dat.token);
				dat.token = lex.lexer(dat);
			}
			
		}
		else
		{
			if((dat.code==3)||(dat.code==1))
			{
				dat.out.print(dat.token);
				dat.token = lex.lexer(dat);
				rest_generator(dat,lex);
			}
			
		}
	}
	
	/*
	Generating the cpp object code of rest expression
	*/
	public static void rest_generator(data dat,Lexer lex)
	{
		
		if((dat.code == 4)&&((dat.token.toString().equalsIgnoreCase("+"))||(dat.token.toString().equalsIgnoreCase("-"))||(dat.token.toString().equalsIgnoreCase("/"))||(dat.token.toString().equalsIgnoreCase("*"))))
		{
			
			dat.out.print(dat.token);
			dat.token = lex.lexer(dat);
			//System.out.println(dat.token);
			expression_generator(dat,lex);
		}
		else{}

	}
	
	public static void condition_generator(data dat,Lexer lex)
	{
		if((dat.code == 6)&&(dat.token.toString().equalsIgnoreCase("(")))
		{
			dat.out.print(dat.token);
			dat.token = lex.lexer(dat);
			
			expression_generator(dat,lex);
			
			if((dat.token.toString().equalsIgnoreCase(">"))||(dat.token.toString().equalsIgnoreCase("<"))||(dat.token.toString().equalsIgnoreCase("="))||(dat.token.toString().equalsIgnoreCase(">="))||(dat.token.toString().equalsIgnoreCase("<="))||(dat.token.toString().equalsIgnoreCase("!=")))
			{
				if(dat.token.toString().equalsIgnoreCase("="))
					dat.out.print("==");
				else
					dat.out.print(dat.token);
				dat.token = lex.lexer(dat);
				expression_generator(dat,lex);
				if((dat.code == 6)&&(dat.token.toString().equalsIgnoreCase(")")))				{
					dat.out.print(dat.token);
					dat.token = lex.lexer(dat);				}
			}
		}
	}


}
